/** 
 * @file Device.c
 * 
 * @detail Description : 
 * MSP430 Related Functions
 * 
 * @author E. Macias / D. Torres / S. Ravindran
 * @author Texas Instruments, Inc
 * @date December, 2011
 * @version 1.0 - Initial version 
 * @note Built with IAR Embedded Workbench: 5.20.1 and CCS Version 5.1.0.09000
 **/

#include "Device.h"
#include "I2C.h"

void Init_Clock (void);
void Set_Vcore_Up (unsigned int level);
void Init_Timer_A(void);
void Init_Board(void);


// Number of samples to calculate the REFO Frequency
#define REFOCLK_SAMPLES           30

// REFO Calculation Variables
boolean_t first_time_capture_flag = false_state;
uint16_t REFOCLK_frequency;
uint16_t REFOCLK_input_captures[REFOCLK_SAMPLES];
uint16_t capture_index = 0;
uint16_t previous_capture_value, new_capture_value = 0;

// USB Communication Receiver or Send Error global variables
BYTE ReceiveError = 0, SendError = 0;
  
/**
* @brief <b>Function Name</b>:     : Init_MCU                                                
* @brief  <b>Description</b>: Stops the watchdog timer, intializes the main 
* clock to 16 Mhz, LEDs, Timer A, and the I2C module. 
* @param Input Parameters: None                               
* @return Return Values: None                                                   
**/
void Init_MCU(void)
{
  // Stop watchdog timer 
  WDTCTL = WDTPW+WDTHOLD;                   
  
  //**************************************************************************//
  BCSCTL1 = CALBC1_16MHZ;                    // Set DCO
  DCOCTL = CALDCO_16MHZ;
  
  // Basic GPIO Initialization
  Init_Board();
  Init_Timer_A();
  
  // Initialze I2C (Settings defined in I2C.h)
  I2C_Master_Init();

  //Initialize UART (Settings defined in UART.h)
  UART_init();
}

/**
* @brief <b>Function Name</b>:     : Init_Timer_A                                                
* @brief  <b>Description</b>: Initializes Timer A0 and A1 to use the ACLK as the 
* source clock. Furthermore, initializes Timer A1 to wake up the MSP430 every 
* SAMPLE_FREQ_HZ to sample the DCM sensors. Timer A0 is used to delay 
* milliseconds using Sleep().
* @param Input Parameters: None                               
* @return Return Values: None                                                    
**/
void Init_Timer_A(void)
{
  // Initialzie Timer A1
  TA1CCTL0 &= ~(CCIE);               // CCR0 interrupt disabled
  TA1CTL = TASSEL_2 + ID_3 + MC_1;         // SMCLK, SMCLK/8 = 2Mhz, Enable up-mode
  
/*
   // Initialize Timer A0
   TA0CTL = TASSEL_1 + ID_0;         // ACLK,  ACLK/1
   TA0CCTL0 &= ~(CCIFG);             // Clear Timer Interrupt Flag
   // Calculate value for sampling at SAMPLE_FREQ_HZ (defined in Device.h)
   TA0CCR0 = (REFOCLK_frequency/SAMPLE_FREQ_HZ); 
   TA0CTL |= MC_1+TACLR;             // Enable up-mode, clear counter register
*/
}

/**
* @brief <b>Function Name</b>:     : Sleep                                                
* @brief  <b>Description</b>: Enables Timer A0, and puts the MSP430 in 
* low-power-mode 0 for delay_ms milliseconds. 
* @param Input Parameters: 
* <BR> unsigned int <b>delay_ms</b> is the number of milliseconds to delay the 
* MSP430 in low power mode 0.                               
* @return Return Values: None                                                    
**/
void Sleep(unsigned int delay_ms)
{
  TA1CCTL0 &= ~(CCIFG);                 // Clear Timer Interrupt Flag
  __bic_SR_register(GIE);	
  TA1CCR0 = (uint16_t)(( 2000 * delay_ms));
  TA1CTL |= TACLR;		       // clear counter register
  TA1CCTL0 |= CCIE;                    // CCR0 interrupt enabled
  __bis_SR_register(LPM1_bits + GIE);  // Enter LPM3 and Enable Global Interrupt
}

/**
* @brief <b>Function Name</b>:     : Init_Board                                                
* @brief  <b>Description</b>: Initializes the unused pins as outputs for low
* power consumption. 
* @param Input Parameters: None                               
* @return Return Values: None                                                      
**/
void Init_Board(void)
{
    // Configure unused ports for low power
  
   P1OUT &= ~(BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7);
   P1DIR |= BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7;
  
   P2OUT &= ~(BIT6 + BIT7);
   P2DIR |= BIT6 + BIT7;

   P3OUT &= ~(BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7);
   P3DIR |= BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7;

}

/**
* @brief <b>Function Name</b>:     : TIMER1_A0_ISR
* @brief  <b>Description</b>: This ISR disables the Timer1 A0 interrupt, and
* exits to active CPU.
* @param Input Parameters: None
* @return Return Values: None
**/
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void)
{
	  TA1CCTL0 &= ~(CCIE);                  	// CCR0 interrupt disabled
	  __bic_SR_register_on_exit(LPM1_bits);  	// Exit active CPU
}
